use crate::workflows::manager::WORKFLOW_MANAGER;
use crate::protocol::task::{SymbolicTask, NominalTask};
use crate::abstractions::fuse::fuse_symbolic;
use crate::protocol::type_derive::IOFixed;
use std::collections::HashMap;

pub fn get_all_tasks_bound(ibound: Option<NominalTask>, obound: Option<NominalTask>, iofixed: IOFixed, force: bool) -> Vec<(String, SymbolicTask, SymbolicTask)> {
    let ibound = ibound.map(|t|SymbolicTask::parse_loose(&t));
    let obound = obound.map(|t|SymbolicTask::parse_loose(&t));
    let manager = WORKFLOW_MANAGER.get().unwrap().lock().unwrap();
    let all_tasks = manager.clone_all_tasks();
    drop(manager);
    let mut result = Vec::new();
    match (ibound, obound) {
        (None, None) => {
            for (name, task) in all_tasks {
                result.push((name, task.clone(), task));
            }
            result
        }
        (Some(ib), None) => {
            for (name, task) in all_tasks {
                if let Some((fused, _)) = fuse_symbolic(&ib, &task, force, iofixed) {
                    result.push((name, task, fused));
                }
            }
            result
        }
        (None, Some(ob)) => {
            for (name, task) in all_tasks {
                if let Some((fused, _)) = fuse_symbolic(&task, &ob, force, iofixed) {
                    result.push((name, task, fused));
                }
            }
            result
        }
        (Some(ib), Some(ob)) => {
            for (name, task) in all_tasks {
                if let Some((fused, _)) = fuse_symbolic(&ib, &task, force, iofixed) {
                    if let Some((fused, _)) = fuse_symbolic(&fused, &ob, force, iofixed) {
                        result.push((name, task, fused));
                        continue;
                    }
                }
                if let Some((fused, _)) = fuse_symbolic(&task, &ob, force, iofixed) {
                    if let Some((fused, _)) = fuse_symbolic(&ib, &fused, force, iofixed) {
                        result.push((name, task, fused));
                        continue;
                    }
                }
            }
            result
        }
    }
}
